ZP_DAMAGE_PER_AP = 500
ZP_AP_PER_DAMAGE = 1
ZP_BURN_TIME = 12

ZP_HUMAN_HEALTH = 100
ZP_HUMAN_ARMOR = 100
ZP_HUMAN_SPEED = 0
ZP_HUMAN_WEAPON = {51,54}
ZP_HUMAN_DMG = {100,120} -- Ranged damage percent
ZP_HUMAN_AMMO = 0 -- [0 = Normal ammo, 1 = Infinite reload, 2 = Infinite bullets]
ZP_HUMAN_JUMP = 0

ZP_SURVIVOR_HEALTH = 3000
ZP_SURVIVOR_WEAPON = {40}
ZP_SURVIVOR_SPEED = 5
ZP_SURVIVOR_ARMOR = 0
ZP_SURVIVOR_DMG = {200,200} -- Ranged damage percent
ZP_SURVIVOR_AMMO = 2
ZP_SURVIVOR_JUMP = 6

ZP_NEMESIS_HEALTH = 20000
ZP_NEMESIS_ARMOR = 0
ZP_NEMESIS_SPEED = 10
ZP_NEMESIS_WEAPON = {}
ZP_NEMESIS_DMG = {200,200} -- Ranged damage percent
ZP_NEMESIS_KNOCKBACK = 0
ZP_NEMESIS_JUMP = 13

ZP_DELAY = 10
ZP_FIRST_ZOMBIE_HEALTH = 2.5

ZP = {}
ZP.CFG = {}
ZP.CFG.ITEM = {}
ZP.CFG.MENUITEM = {}
ZP.CFG.ADMIN = {}
ZP.CFG.EXTRAHUMAN = {}
ZP.CFG.EXTRAZOMBIE = {}
USGN = {}
dofile("sys/lua/ZP/menu.lua")

function ZP.CreateExtraItem(team,data)
	if team == "human" then
		local id = #ZP.CFG.EXTRAHUMAN + 1
		ZP.CFG.EXTRAHUMAN[id] = data or {}
		return id
	elseif team == "zombie" then
		local id = #ZP.CFG.EXTRAZOMBIE + 1
		ZP.CFG.EXTRAZOMBIE[id] = data or {}
		return id
	end
end

function ZP.CreateClass(data)
	local id = #ZP.Class + 1
	ZP.Class[id] = data or {}
	return id
end

ZP.Class = {
	[0] = {
		Name = "Default Zombie",
		Description = "HP+- Speed+- DMG+- Knockback+-",
		Health = 3000,
		Armor = 0,
		Speed = 3,
		Dmg = {120,120}, -- Ranged damage percent
		Knockback = 100,
		ExtraWeapon = {}
	}
}

ItemCount = -1
IN = {}
IN[-1] = "Ingition"
IN[0] = "Damage Entity"
IN[10] = "M3 Super 90"
IN[11] = "XM1014 M4"
IN[20] = "MP5 Navy"
IN[21] = "Schmidt TMP"
IN[22] = "ES P90"
IN[30] = "AK-47 Kalashnikov"
IN[32] = "M4A1 Carbine"
IN[33] = "Steyr AUG A1"
IN[34] = "Schmidt Scout"
IN[35] = "AWP Magnum Sniper"
IN[38] = "IMI Galil"
IN[40] = "M249 Para Machinegun"
IN[251] = "Explosion"
IN[253] = "Turret"
IN[254] = "Gate Field"
IN[255] = "Barbed Wire"

function ItemName(id)
	return IN[id] or itemtype(id,"name") or "Unknown Item"
end

function CreateItem(name)
	local id = ItemCount - 1
	ItemCount = id

	IN[id] = name
	return id
end

function ZP.LoadCFG()
	local f = io.open("sys/lua/ZP/config.txt","r")
	if f then
		for line in f:lines() do
			if string.sub(line,1,7) == "#ITEMS " then
				line = string.sub(line,8)
				local find = string.find(line," ")
				if find then
					local ConfigClass = string.sub(line,1,find-1)
					local Items = string.split(string.sub(line,find+1),",")

					ZP.CFG.MENUITEM[ConfigClass] = {}
					for i = 1, #Items do
						ZP.CFG.MENUITEM[ConfigClass][i] = tonumber(Items[i])
					end
				end
			elseif string.sub(line,1,7) == "#ADMIN " then
				local usgn = tonumber(string.sub(line,8))
				if usgn then
					ZP.CFG.ADMIN[usgn] = true
				end
			elseif string.sub(line,1,13) == "#ZOMBIECLASS " then
				local script = string.sub(line,14)
				if string.len(script) > 0 then
					dofile("sys/lua/ZP/classes/"..script)
				end
			elseif string.sub(line,1,7) == "#EXTRA " then
				local script = string.sub(line,8)
				if string.len(script) > 0 then
					dofile("sys/lua/ZP/extraitems/"..script)
				end
			end
		end
		f:close()
	end

	local f = io.open("sys/lua/ZP/parsed.txt","r")
	if f then
		for line in f:lines() do
			parse(line)
		end
		f:close()
	end
end

function ZP.LoadMenus()
	local PrimaryMenuList = ItemName(ZP.CFG.MENUITEM["PRIMARY"][1])
	for i = 2, #ZP.CFG.MENUITEM["PRIMARY"] do
		PrimaryMenuList = PrimaryMenuList..","..ItemName(ZP.CFG.MENUITEM["PRIMARY"][i])
	end
	primaryWeaponMenu = createMenu("Primary weapon,"..PrimaryMenuList,
		function (id,men,page,obj,button)
			if button > 0 then
				if player(id,"team") == 2 then
					if PLAYER[id].Survivor then
						ZP.Msg2(id,"Survivors can't equip menu weapons",255,0,0)
					else
						parse("equip "..id.." "..ZP.CFG.MENUITEM["PRIMARY"][button])
					end
				else
					ZP.Msg2(id,"Weapons are for humans",255,0,0)
				end
			end
			secondaryWeaponMenu.openTo(id,1)
		end
	)

	local SecondaryMenuList = ItemName(ZP.CFG.MENUITEM["SECONDARY"][1])
	for i = 2, #ZP.CFG.MENUITEM["SECONDARY"] do
		SecondaryMenuList = SecondaryMenuList..","..ItemName(ZP.CFG.MENUITEM["SECONDARY"][i])
	end
	secondaryWeaponMenu = createMenu("Secondary weapon,"..SecondaryMenuList,
		function (id,men,page,obj,button)
			if button > 0 then
				if player(id,"team") == 2 then
					if PLAYER[id].Survivor then
						ZP.Msg2(id,"Survivors can't equip menu weapons",255,0,0)
					else
						parse("equip "..id.." "..ZP.CFG.MENUITEM["SECONDARY"][button])
					end
				else
					ZP.Msg2(id,"Weapons are for humans",255,0,0)
				end
			end
		end
	)

	if #ZP.CFG.EXTRAHUMAN > 0 then
		local HumanExtraItems = ""
		for i = 1, #ZP.CFG.EXTRAHUMAN do
			HumanExtraItems = HumanExtraItems..","..ZP.CFG.EXTRAHUMAN[i].Name.."|"..ZP.CFG.EXTRAHUMAN[i].Cost.." Ammo Packs"
		end
		humanExtraItemMenu = createMenu("Human - Buy Extra Items@b"..HumanExtraItems,
			function (id,men,page,obj,button)
				if player(id,"team") ~= 2 then
					return ZP.Msg2(id,"Only humans can buy these items",255,0,0)
				end
				if PLAYER[id].Survivor then
					return ZP.Msg2(id,"Survivors can't buy extra items",255,0,0)
				end
				if button > 0 then
					if PLAYER[id].get("AmmoPacks") >= ZP.CFG.EXTRAHUMAN[button].Cost then
						if ZP.CFG.EXTRAHUMAN[button].Equipable(id) then
							ZP.CFG.EXTRAHUMAN[button].Equip(id)
							PLAYER[id].set("AmmoPacks", PLAYER[id].get("AmmoPacks")-ZP.CFG.EXTRAHUMAN[button].Cost)
							ZP.Msg2(id,"You have bought "..ZP.CFG.EXTRAHUMAN[button].Name,0,255,0)
							PLAYER[id].UpdateHuds()
						else
							ZP.Msg2(id,"You have already got this item",255,0,0)
						end
					else
						ZP.Msg2(id,"Not enough ammo packs",255,0,0)
					end
				end
			end
		)
	end

	if #ZP.CFG.EXTRAZOMBIE > 0 then
		local ZombieExtraItems = ""
		for i = 1, #ZP.CFG.EXTRAZOMBIE do
			ZombieExtraItems = ZombieExtraItems..","..ZP.CFG.EXTRAZOMBIE[i].Name.."|"..ZP.CFG.EXTRAZOMBIE[i].Cost.." Ammo Packs"
		end
		zombieExtraItemMenu = createMenu("Zombie - Buy Extra Items@b"..ZombieExtraItems,
			function (id,men,page,obj,button)
				if player(id,"team") ~= 1 then
					return ZP.Msg2(id,"Only zombies can buy these items",255,0,0)
				end
				if PLAYER[id].Nemesis then
					return ZP.Msg2(id,"Nemesis can't buy extra items",255,0,0)
				end
				if button > 0 then
					if PLAYER[id].get("AmmoPacks") >= ZP.CFG.EXTRAZOMBIE[button].Cost then
						local equipable, reason = ZP.CFG.EXTRAZOMBIE[button].Equipable(id)
						if equipable then
							ZP.CFG.EXTRAZOMBIE[button].Equip(id)
							PLAYER[id].set("AmmoPacks", PLAYER[id].get("AmmoPacks")-ZP.CFG.EXTRAZOMBIE[button].Cost)
							ZP.Msg2(id,"You have bought "..ZP.CFG.EXTRAZOMBIE[button].Name,0,255,0)
							PLAYER[id].UpdateHuds()
						else
							ZP.Msg2(id,reason or "You cannot equip this item",255,0,0)
						end
					else
						ZP.Msg2(id,"Not enough ammo packs",255,0,0)
					end
				end
			end
		)
	end

	mainMenu = createMenu("Zombie Plague Xtreme,Buy Items,Choose class,Unstuck,Go spectator,Help,Admin Menu",
		function (id,men,page,obj,button)
			if button == 1 then
				if player(id,"team") == 2 and humanExtraItemMenu then
					humanExtraItemMenu.openTo(id,1)
				elseif player(id,"team") == 1 and zombieExtraItemMenu then
					zombieExtraItemMenu.openTo(id,1)
				end
			elseif button == 2 then
				classMenu.openTo(id,1)
			elseif button == 3 then
				if player(id,"team") == 1 then
					local x = (player(id,"tilex")*32) + 16
					local y = (player(id,"tiley")*32) + 16
					parse("setpos "..id.." "..x.." "..y)
				else
					ZP.Msg2(id,"Functionality only available for zombies",255,0,0)
				end
			elseif button == 4 then
				PLAYER[id].enableSwitchTeam()
				PLAYER[id].Survivor = false
				PLAYER[id].Nemesis = false
				PLAYER[id].UpdateGlow()
				parse("makespec "..id)
			elseif button == 6 then
				if PLAYER[id].Admin() then
					adminMenu.openTo(id,1)
				else
					ZP.Msg2(id,"Admin menu is only available for admins",255,0,0)
				end
			end
		end
	)

	adminMenu = createMenu("Admin Menu,Make Survivor,Make Nemesis,Make Human,Make Zombie",
		function (id,men,page,obj,button)
			if button == 1 then
				makeSurvivorMenu.openTo(id,1)
			elseif button == 2 then
				makeNemesisMenu.openTo(id,1)
			elseif button == 3 then
				makeHumanMenu.openTo(id,1)
			elseif button == 4 then
				makeZombieMenu.openTo(id,1)
			end
		end
	)

	local ZombieClassesList = ""
	for i = 1, #ZP.Class do
		ZombieClassesList = ZombieClassesList..","..ZP.Class[i].Name.."|"..ZP.Class[i].Description
	end

	classMenu = createMenu("Zombie - Choose class@b"..ZombieClassesList,
		function (id,men,page,obj,button)
			if button > 0 then
				PLAYER[id].NextClass = button
				ZP.Msg2(id,"Your new class will be "..ZP.Class[button].Name,255,0,0)
			end
		end
	)

	local PlayerIDList = ""
	for i = 1, 32 do PlayerIDList = PlayerIDList..","..i end
	makeSurvivorMenu = createMenu("Admin Menu - Make Survivor"..PlayerIDList,
		function (id,men,page,obj,button)
			if button > 0 then
				if player(button,"exists") then
					PLAYER[button].MakeSurvivor()
				end
				makeSurvivorMenu.openTo(id,page)
			end
		end
	)

	makeNemesisMenu = createMenu("Admin Menu - Make Nemesis"..PlayerIDList,
		function (id,men,page,obj,button)
			if button > 0 then
				if player(button,"exists") then
					PLAYER[button].MakeNemesis()
				end
				makeNemesisMenu.openTo(id,page)
			end
		end
	)

	makeHumanMenu = createMenu("Admin Menu - Make Human"..PlayerIDList,
		function (id,men,page,obj,button)
			if button > 0 then
				if player(button,"exists") then
					PLAYER[button].MakeHuman()
				end
				makeHumanMenu.openTo(id,page)
			end
		end
	)

	makeZombieMenu = createMenu("Admin Menu - Make Zombie"..PlayerIDList,
		function (id,men,page,obj,button)
			if button > 0 then
				if player(button,"exists") then
					PLAYER[button].MakeZombie()
				end
				makeZombieMenu.openTo(id,page)
			end
		end
	)

	local _getButtonName = {}
	for i = 1, 32 do
		_getButtonName[i] = function()
			if player(i,"exists") then return player(i,"name") end
			return ""
		end

		makeSurvivorMenu.buttonFunc[i] = _getButtonName[i]
		makeNemesisMenu.buttonFunc[i] = _getButtonName[i]
		makeHumanMenu.buttonFunc[i] = _getButtonName[i]
		makeZombieMenu.buttonFunc[i] = _getButtonName[i]
	end
end

function ZP.Print(txt,r,g,b)
	if r and g and b then txt = Color(r,g,b)..txt end
	print(txt)
end

function ZP.Msg(txt,r,g,b)
	if string.sub(txt,string.len(txt)-1,string.len(txt)) == "@C" then
		if r and g and b then txt = Color(r,g,b)..txt end
		msg(txt)
	else
		if r and g and b then
			msg(Color(r,g,b).."[ZP] "..txt)
		else
			msg("[ZP] "..txt)
		end
	end
end

function ZP.Msg2(id,txt,r,g,b)
	if string.sub(txt,string.len(txt)-1,string.len(txt)) == "@C" then
		if r and g and b then txt = Color(r,g,b)..txt end
		msg2(id,txt)
	else
		if r and g and b then
			msg2(id,Color(r,g,b).."[ZP] "..txt)
		else
			msg2(id,"[ZP] "..txt)
		end
	end
end

function USGN.New(id)
	local u = {}
	u.Data = {}

	function u.setData(d,value)
		u.Data[d] = value
	end

	function u.getData(d,value)
		return u.Data[d]
	end

	function u.Save()
		local f = io.open("sys/lua/ZP/data/"..id..".txt","w")
		for DataName, value in pairs(u.Data) do
			f:write(DataName.." "..type(value).." "..value.."\n")
		end

		f:close()
	end

	function u.Load()
		local f = io.open("sys/lua/ZP/data/"..id..".txt","r")
		if f then
			for line in f:lines() do
				local content = line:split()

				if content[1] then
					local DataName = content[1]
					local t = content[2]
					local value
					if t == "number" then value = tonumber(content[3]) end
					if t == "string" then value = content[3] end

					u.Data[DataName] = value
				end
			end

			f:close()
		end
	end

	function u.Admin()
		return ZP.CFG.ADMIN[id]
	end

	function u.UpdateHuds()
		for _, p in pairs(player(0,"table")) do
			if PLAYER[p].USGN == id then
				PLAYER[p].UpdateHud()
			end
		end
	end

	u.Load(); USGN[id] = u
	return u
end

function USGN.Get(id)
	if id == 0 then return nil end
	if USGN[id] then return USGN[id] end
	return USGN.New(id)
end

function AngleBetween(fromx,fromy,tox,toy)
	local Angle = math.atan2(fromy-toy,fromx-tox) - math.pi/2
	if Angle < -math.pi then Angle = Angle + (math.pi*2) end
	return Angle
end

function Sound3(file,x,y,radius)
	for _, id in pairs(player(0,"table")) do
		if math.sqrt((x-player(id,"x"))^2 + (y-player(id,"y"))^2) < radius then
			parse("sv_sound2 "..id.." "..file)
		end
	end
end

function string.split(txt,d)
	if not d then d = " " end
	local split = {}
	local lastPos = 1
	for i = 1, string.len(txt)+1 do
		if string.sub(txt,i,i+string.len(d)-1) == d or i == string.len(txt)+1 then
			local newSplit = string.sub(txt,lastPos,i-1)
			table.insert(split,newSplit)
			lastPos = i + string.len(d)
		end
	end
	return split
end

function table.find(t,val)
	for k, v in pairs(t) do
		if v == val then
			return k
		end
	end
end

function Color(r,g,b)
	r,g,b = tostring(r),tostring(g),tostring(b)
	while string.len(r) < 3 do r = "0"..r end
	while string.len(g) < 3 do g = "0"..g end
	while string.len(b) < 3 do b = "0"..b end
	if string.len(r) == 3 and string.len(g) == 3 and string.len(b) == 3 then
		return ""..r..g..b
	end
	return "000000000"
end

function Millisecs()
	return os.clock() * 1000
end

function newPlayer(id)
	local p = {}
	p.USGN = 0
	p.Exist = false

	function p.ClassName()
		if player(id,"team") == 1 then
			if p.Nemesis then return "Nemesis" end
			if ZP.Class[p.Class] then return ZP.Class[p.Class].Name end
			return "None"
		elseif player(id,"team") == 2 then
			if p.Survivor then return "Survivor" end
			return "Human"
		end
		return "Spectator"
	end

	function p.HudColor()
		if player(id,"team") == 1 then
			if p.Nemesis then
				return 255, 0, 0
			else
				return 255, 255, 0
			end
		elseif player(id,"team") == 2 then
			return 0, 0, 255
		end
		return 255, 255, 255
	end

	function p.Hudtxt(h,txt,x,y,r,g,b)
		if r and g and b then txt = Color(r,g,b)..txt end
		if p.HUD[h] ~= txt then
			parse('hudtxt2 '..id..' '..h..' "'..txt..'" '..x..' '..y)
			p.HUD[h] = txt
		end
	end

	function p.CleanHud(h)
		p.Hudtxt(h,"",0,0)
	end

	function p.Knockback(fx,fy,dist)
		if p.Nemesis then
			dist = math.floor((dist/100) * ZP_NEMESIS_KNOCKBACK)
		else
			dist = math.floor((dist/100) * ZP.Class[p.Class].Knockback)
		end

		if dist > 0 then
			local Angle = AngleBetween(fx,fy,player(id,"x"),player(id,"y"))
			local x = player(id,"x") + math.sin(Angle) * dist
			local y = player(id,"y") - math.cos(Angle) * dist
			local checkX = player(id,"x") + math.sin(Angle) * (dist+8)
			local checkY = player(id,"y") - math.cos(Angle) * (dist+8)
			if tile(math.floor(checkX/32),math.floor(checkY/32),"walkable") then
				parse("setpos "..id.." "..math.floor(x).." "..math.floor(y))
			end
		end
	end

	function p.get(data)
		if p.USGN > 0 then
			return USGN.Get(p.USGN).getData(data) or p.Data[data]
		end
		return p.Data[data]
	end

	function p.set(data,value)
		if p.USGN > 0 then
			USGN.Get(p.USGN).setData(data,value)
		else
			p.Data[data] = value
		end
	end

	function p.InitData()
		if p.USGN > 0 then
			USGN.Get(p.USGN)
		end
		p.Data = {}
		p.Data["AmmoPacks"] = 0
		p.Data["Damage"] = 0
	end

	function p.RemoveGlow()
		if p.Glow then
			freeimage(p.Glow)
			p.Glow = nil
		end
	end

	function p.CreateGlow(r,g,b)
		p.Glow = image("gfx/sprites/flare2.bmp",0,1,100+id)
		imageblend(p.Glow,1)
		imagecolor(p.Glow,r,g,b)

		tween_scale(p.Glow,150,2.5,2.5)
	end

	function p.MakeHuman()
		p.Survivor = false
		p.Nemesis = false
		p.UpdateGlow()

		local x, y = player(id,"x"), player(id,"y")

		if player(id,"team") ~= 2 then
			p.enableSwitchTeam()
			parse("makect "..id)
		end
		if x > 0 and y > 0 then
			parse("spawnplayer "..id.." "..x.." "..y)
		end
	end

	function p.MakeZombie()
		p.Survivor = false
		p.Nemesis = false
		p.UpdateGlow()

		local x, y = player(id,"x"), player(id,"y")

		if player(id,"team") ~= 1 then
			p.enableSwitchTeam()
			parse("maket "..id)
		end
		if x > 0 and y > 0 then
			parse("spawnplayer "..id.." "..x.." "..y)
		end
	end

	function p.MakeSurvivor()
		if ZP_COUNT_DOWN >= 0 then
			for _, pl in pairs(player(0,"tableliving")) do
				if pl ~= id and player(pl,"team") ~= 1 then PLAYER[pl].MakeZombie() end
			end
			ZP.Msg(player(id,"name").." IS THE SURVIVOR!@C",0,0,255)
			ZP_COUNT_DOWN = -1
		else
			ZP.Msg(player(id,"name").." IS A SURVIVOR!@C",0,0,255)
		end
		parse("sv_sound starkkz/zombie/survivor"..math.random(1,2)..".wav")

		p.Survivor = true
		p.Nemesis = false

		local x, y = player(id,"x"), player(id,"y")
		if player(id,"team") ~= 2 then
			p.enableSwitchTeam()
			parse("makect "..id)
		end
		if x > 0 and y > 0 then
			parse("spawnplayer "..id.." "..x.." "..y)
		end
	end

	function p.MakeNemesis()
		if ZP_COUNT_DOWN >= 0 then
			for _, pl in pairs(player(0,"tableliving")) do
				if pl ~= id and player(pl,"team") ~= 2 then PLAYER[pl].MakeHuman() end
			end
			ZP.Msg(player(id,"name").." IS THE NEMESIS!@C",255,0,0)
			ZP_COUNT_DOWN = -1
		else
			ZP.Msg(player(id,"name").." IS A NEMESIS!@C",255,0,0)
		end
		parse("sv_sound starkkz/zombie/nemesis"..math.random(1,2)..".ogg")

		p.Survivor = false
		p.Nemesis = true

		local x, y = player(id,"x"), player(id,"y")
		if player(id,"team") ~= 1 then
			p.enableSwitchTeam()
			parse("maket "..id)
		end
		if x > 0 and y > 0 then
			parse("spawnplayer "..id.." "..x.." "..y)
		end
	end

	function p.UpdateGlow()
		p.RemoveGlow()
		if player(id,"exists") then
			if p.Nemesis then
				p.CreateGlow(255,0,0)
			elseif p.Survivor then
				p.CreateGlow(255,255,255)
			end
		end
	end

	function p.Admin()
		if p.USGN > 0 then
			return USGN.Get(p.USGN).Admin()
		end
		return false
	end

	function p.CleanImagesID()
		p.Glow = nil
		p.Look = nil
	end

	function p.Init()
		p.Data = {}
		p.InitData()

		p.Jump = 0
		p.lastJump = 0
		p.NextClass = 0
		p.HealthProtection = 0
		p.ArmorProtection = 0
		p.Class = 0
		p.Survivor = false
		p.Nemesis = false
		p.InfClip = false
		p.DamageMessage = Millisecs()
		p.KnockSlow = 0
		p.disableSwitchTeam()
		p.lastPainSound = 0
		p.BurnTime = 0
		p.lastBurnSound = 0
		p.lastBurnEffect = 0
		p.JumpAuth = false

		p.HUD = {}
	end

	function p.Always()
		if player(id,"team") == 1 then
			if Millisecs() - p.BurnTime <= 0 then
				if Millisecs() - p.lastBurnEffect >= 0 then
					p.lastBurnEffect = Millisecs() + 300
					parse('effect "fire" '..player(id,"x")..' '..player(id,"y")..' 30 30')
				end

				local soundDuration = {3669,1338,1583}
				if Millisecs() - p.lastBurnSound > 0 then
					local burnSound = math.random(1,3)

					p.lastBurnSound = Millisecs() + soundDuration[burnSound]
					if not p.Nemesis then
						local playSoundAuth = 1
						if ZP.Class[p.Class].IgnitePain then
							playSoundAuth = ZP.Class[p.Class].IgnitePain(id) or 1
						end
						if playSoundAuth == 1 then
							Sound3("starkkz/zombie/burn_"..burnSound..".ogg", player(id,"x"), player(id,"y"), 320)
						end
					end
					ZP.Hit(id, 0, -1, math.floor(soundDuration[burnSound]/100)+math.random(-5,5))
				end
			end

			if ZP.Class[p.Class].Always and not p.Nemesis then
				ZP.Class[p.Class].Always(id)
			end
		end

		if Millisecs() - p.DamageMessage >= 2000 then
			p.CleanHud(2)
		end

		if p.Jump > 0 then
			local Ang = math.rad(player(id,"rot"))
			local x = player(id,"x") + math.sin(Ang) * p.Jump
			local y = player(id,"y") - math.cos(Ang) * p.Jump

			p.Jump = p.Jump - 0.25
			if not tile(math.floor(x/32),math.floor(y/32),"wall") then
				parse("setpos "..id.." "..x.." "..y)

				if ZP.Class[p.Class].JumpMovement and player(id,"team") == 1 and not p.Nemesis then
					ZP.Class[p.Class].JumpMovement(id,x,y)
				end
				p.lastJump = Millisecs()
			else
				p.Jump = 0
			end
		end

		if p.KnockSlow > 100 then p.KnockSlow = 100 end
		if p.KnockSlow > 0 then p.KnockSlow = p.KnockSlow - 0.25 end
		p.UpdateSpeed()
	end

	function p.UpdateHud()
		p.Hudtxt(1,"Ammo packs: "..p.get("AmmoPacks").." - Class: "..p.ClassName().." - Health "..p.HealthProtection.." - Armor "..p.ArmorProtection,15,425,p.HudColor())
	end

	function p.UpdateHuds()
		if p.USGN > 0 then
			USGN.Get(p.USGN).UpdateHuds()
		else
			p.UpdateHud()
		end
	end

	function p.UpdateProtection()
		if p.HealthProtection > 0 then
			parse("sethealth "..id.." "..p.HealthProtection)
		end

		if player(id,"team") == 1 and not p.Nemesis then
			if ZP.Class[p.Class].Invisible then
				return parse("setarmor "..id.." 206")
			end
		end
		if p.ArmorProtection <= 200 then
			parse("setarmor "..id.." "..p.ArmorProtection)
		else
			parse("setarmor "..id.." 200")
		end
	end

	function p.Save()
		if p.USGN > 0 then
			USGN.Get(p.USGN).Save()
		end
	end

	function p.Speed()
		if p.Jump > 0 then return -100 end
		if player(id,"team") == 1 then
			if p.Nemesis then
				return ZP_NEMESIS_SPEED - p.KnockSlow
			end
			return ZP.Class[p.Class].Speed - p.KnockSlow
		elseif player(id,"team") == 2 then
			if p.Survivor then
				return ZP_SURVIVOR_SPEED - p.KnockSlow
			end
			return ZP_HUMAN_SPEED - p.KnockSlow
		end
		return 0
	end

	function p.UpdateSpeed()
		if player(id,"speedmod") ~= math.floor(p.Speed()) then
			parse("speedmod "..id.." "..math.floor(p.Speed()))
		end
	end

	function p.disableSwitchTeam()
		p.allowSwitchTeam = false
		if player(id,"exists") then
		end
	end

	function p.enableSwitchTeam()
		p.allowSwitchTeam = true
		if player(id,"exists") then
		end
	end

	function p.JumpAction()
		if p.Jump == 0 then
			if player(id,"team") == 1 then
				if p.Nemesis then
					if Millisecs() - p.lastJump >= 1000 then
						p.Jump = ZP_NEMESIS_JUMP
					end
				else
					local jump = ZP.Class[p.Class].Jump
					if jump then
						if Millisecs() - p.lastJump >= ZP.Class[p.Class].JumpDelay then
							p.Jump = jump
						end
					elseif p.JumpAuth then
						p.Jump = 6
					end
				end
			elseif player(id,"team") == 2 then
				if p.Survivor then
					p.Jump = ZP_SURVIVOR_JUMP
				else
					if ZP_HUMAN_JUMP > 0 then
						if p.JumpAuth and 6 < ZP_HUMAN_JUMP then
							p.Jump = ZP_HUMAN_JUMP
						else
							p.Jump = 6
						end
					elseif p.JumpAuth then
						p.Jump = 6
					end
				end
			end
		end
	end

	p.Init()
	return p
end

PLAYER = {}
for i = 1, 32 do
	PLAYER[i] = newPlayer(i)
	PLAYER[i].disableSwitchTeam()
end
ZP_COUNT_DOWN = ZP_DELAY
ZP_ROUND_END = false

function ZP.AddTimer(delay,f,params,restartClean)
	local t = {delay = Millisecs() + delay,f = f,params = params,clean = restartClean}
	table.insert(_Timer,t)
end

_Timer = {}
addhook("always","ZP.Always")
function ZP.Always()
	for _, id in pairs(player(0,"table")) do
		PLAYER[id].Always()
	end

	for k, v in pairs(_Timer) do
		if Millisecs() - v.delay > 0 then
			v.f(unpack(v.params))
			_Timer[k] = nil
		end
	end

	for _, i in pairs(ZP.CFG.EXTRAHUMAN) do
		if i.Always then
			i.Always()
		end
	end

	for _, i in pairs(ZP.CFG.EXTRAZOMBIE) do
		if i.Always then
			i.Always()
		end
	end

	for i = 1, 32 do
		if player(i,"exists") and not PLAYER[i].Exist then
			if player(i,"bot") then
				ZP.Join(i)
			end
			PLAYER[i].Exist = true
		elseif not player(i,"exists") and PLAYER[i].Exist then
			ZP.Leave(i)
			PLAYER[i].Exist = false
		end
	end
end

function ZP.Leave(id)
	PLAYER[id].Save()
end

addhook("use","ZP.Use")
function ZP.Use(id,event)
	if event == 0 then
		PLAYER[id].JumpAction()
	end
end

addhook("join","ZP.Join")
function ZP.Join(id)
	PLAYER[id].USGN = player(id,"usgn") or 0
	PLAYER[id].Init()
	PLAYER[id].enableSwitchTeam()

	if player(id,"bot") then
		PLAYER[id].MakeHuman()
		PLAYER[id].NextClass = math.random(1,#ZP.Class)
	end
end

addhook("spawn","ZP.Spawn")
function ZP.Spawn(id)
	PLAYER[id].UpdateGlow()

	PLAYER[id].Class = PLAYER[id].NextClass
	if player(id,"team") == 1 then
		if PLAYER[id].Nemesis then
			PLAYER[id].HealthProtection = ZP_NEMESIS_HEALTH
			PLAYER[id].ArmorProtection = ZP_NEMESIS_ARMOR

			for _, w in pairs(ZP_NEMESIS_WEAPON) do
				parse("equip "..id.." "..w)
			end

			ZP.Msg2(id,"Your class allows you to jump, hit [E] to jump",0,255,0)
		else
			PLAYER[id].HealthProtection = ZP.Class[PLAYER[id].Class].Health
			PLAYER[id].ArmorProtection = ZP.Class[PLAYER[id].Class].Armor

			for _, w in pairs(ZP.Class[PLAYER[id].Class].ExtraWeapon) do
				parse("equip "..id.." "..w)
			end

			if ZP.Class[PLAYER[id].Class].Jump then
				ZP.Msg2(id,"Your class allows you to jump, hit [E] to jump",0,255,0)
			end
		end

		if ZP.Class[PLAYER[id].Class].Spawn then
			ZP.Class[PLAYER[id].Class].Spawn(id)
		end
	elseif player(id,"team") == 2 then
		if PLAYER[id].Survivor then
			PLAYER[id].HealthProtection = ZP_SURVIVOR_HEALTH
			PLAYER[id].ArmorProtection = ZP_SURVIVOR_ARMOR

			for _, w in pairs(ZP_SURVIVOR_WEAPON) do
				parse("equip "..id.." "..w)
			end
			if ZP_SURVIVOR_WEAPON[1] then
				parse("setweapon "..id.." "..ZP_SURVIVOR_WEAPON[1])
			end
		else
			PLAYER[id].HealthProtection = ZP_HUMAN_HEALTH
			PLAYER[id].ArmorProtection = ZP_HUMAN_ARMOR

			for _, w in pairs(ZP_HUMAN_WEAPON) do
				parse("equip "..id.." "..w)
			end
			primaryWeaponMenu.openTo(id,1)

			if player(id,"bot") then
				local primary = ZP.CFG.MENUITEM["PRIMARY"]
				local secondary = ZP.CFG.MENUITEM["SECONDARY"]

				parse("equip "..id.." "..primary[math.random(1,#primary)])
				parse("equip "..id.." "..secondary[math.random(1,#secondary)])
			end
			parse("setweapon "..id.." 50")
		end
		parse("strip "..id.." 1")
	elseif player(id,"team") == 0 then
	end

	PLAYER[id].Jump = 0
	PLAYER[id].KnockSlow = 0

	PLAYER[id].UpdateSpeed()
	PLAYER[id].UpdateProtection()
	PLAYER[id].UpdateHuds()
	if not ZP_ROUND_END then
		PLAYER[id].UpdateGlow()
	end
	parse("setmaxhealth "..id.." 255")

	if player(id,"team") == 1 then return "78" end
end

addhook("projectile","ZP.Projectile")
function ZP.Projectile(id,w,x,y)
	if w == 51 then
		for i = 1, 3 do
			local img = image("gfx/sprites/wave.bmp",0,1,0)
			imageblend(img,1)
			imagecolor(img,255,0,0)
			imagepos(img,x,y,0)
			tween_scale(img,1000,i*2,i*2)
			ZP.AddTimer(1000,freeimage,{img},true)
		end
	elseif w == 54 then
		local img = image("gfx/sprites/flare2.bmp",0,1,0)
		imageblend(img,1)
		imagepos(img,x,y,0)
		tween_scale(img,1000,3.5,3.5)
	end
end

addhook("die","ZP.Die")
function ZP.Die(id)
	if PLAYER[id].Survivor then
		return 1
	end
	local playSoundAuth = 1
	if player(id,"team") == 1 and not PLAYER[id].Nemesis then
		if ZP.Class[PLAYER[id].Class].Die then
			playSoundAuth = ZP.Class[PLAYER[id].Class].Die(id) or 1
		end
	end
	if player(id,"team") == 1 then
		if playSoundAuth == 1 then
			Sound3("starkkz/zombie/die_"..math.random(1,3)..".ogg",player(id,"x"),player(id,"y"),380)
		end
		return 1
	end
end

addhook("walkover","ZP.Walkover")
function ZP.Walkover(id)
	if PLAYER[id].Survivor then
		return 1
	end
end

addhook("drop","ZP.Drop")
function ZP.Drop(id)
	if PLAYER[id].Survivor then
		return 1
	end
	if player(id,"team") == 1 then return 1 end
end

addhook("buy","ZP.Buy")
function ZP.Buy()
	return 1
end

addhook("minute","ZP.Minute")
function ZP.Minute()
	parse("sv_sound starkkz/zombie/thunder.wav")
	for _, id in pairs(player(0,"table")) do
		if player(id,"team") == 1 and player(id,"health") > 0 then
			local Snd = {2,3,5,6,11,14}
			parse("sv_sound2 "..id.." starkkz/zombie/nil_snd_"..Snd[math.random(1,#Snd)]..".wav")
		end
	end
end

addhook("second","ZP.Second")
function ZP.Second()
	if ZP_COUNT_DOWN > 0 then
		ZP.Msg(ZP_COUNT_DOWN.."@C",255,0,0)
		if ZP_COUNT_DOWN <= 10 then
			parse("sv_sound starkkz/zombie/timer_"..ZP_COUNT_DOWN..".wav")
		end

		ZP_COUNT_DOWN = ZP_COUNT_DOWN - 1
	elseif ZP_COUNT_DOWN == 0 then

		local players = player(0,"tableliving")

		if #players > 0 then
			local gameMode = math.random(1,5)
			local id = players[math.random(1,#players)]

			if gameMode == 1 then
				-- Zombies VS Survivor
				PLAYER[id].MakeSurvivor()
			elseif gameMode == 2 then
				-- Humans VS Nemesis
				PLAYER[id].MakeNemesis()
			elseif gameMode >= 3 then
				-- First zombie
				PLAYER[id].MakeZombie()
				PLAYER[id].HealthProtection = math.floor(PLAYER[id].HealthProtection * ZP_FIRST_ZOMBIE_HEALTH)

				ZP.Msg(player(id,"name").." IS THE FIRST ZOMBIE!@C",255,0,0)
			end

			PLAYER[id].UpdateHuds()
		end

		for i = 1, 32 do
			PLAYER[i].disableSwitchTeam()
		end
		ZP_COUNT_DOWN = -1
	end

	for _, id in pairs(player(0,"table")) do
		if player(id,"team") == 1 and not PLAYER[id].Nemesis then
			if ZP.Class[PLAYER[id].Class].onSecond then
				ZP.Class[PLAYER[id].Class].onSecond(id)
			end
		end
	end
end

addhook("team","ZP.Team")
function ZP.Team(id,team)
	if not PLAYER[id].allowSwitchTeam then
		return 1
	end
	PLAYER[id].disableSwitchTeam()
end

addhook("startround","ZP.Start")
function ZP.Start()
	ZP_ROUND_END = false
	ZP_COUNT_DOWN = ZP_DELAY
	for k, v in pairs(_Timer) do
		if v.clean then
			_Timer[k] = nil
		end
	end

	for i = 1, #ZP.Class do
		if ZP.Class[i].Startround then
			ZP.Class[i].Startround()
		end
	end

	for i = 1, 32 do
		PLAYER[i].InfClip = false
		PLAYER[i].Nemesis = false
		PLAYER[i].JumpAuth = false
		PLAYER[i].Survivor = false
		PLAYER[i].enableSwitchTeam()
		PLAYER[i].CleanImagesID()

		if player(i,"exists") then
			if player(i,"team") == 0 then
				ZP.Msg2(i,"You can choose team until the countdown reaches zero")
			else
				PLAYER[i].MakeHuman()
			end
		end
	end
end

addhook("endround","ZP.End")
function ZP.End()
	ZP_ROUND_END = true
	local humanCount = {}
	for _, id in pairs(player(0,"table")) do
		if player(id,"team") == 2 and player(id,"health") > 0 then
			table.insert(humanCount,id)
		end
	end

	if #humanCount > 0 then
		parse("sv_sound starkkz/zombie/win_humans1.wav")
		for _, id in pairs(humanCount) do
			PLAYER[id].set("AmmoPacks", PLAYER[id].get("AmmoPacks")+5)
			PLAYER[id].UpdateHuds()
		end
		ZP.Msg("Humans survived the plague!@C",0,0,255)
	else
		parse("sv_sound starkkz/zombie/the_horror.wav")
		ZP.Msg("Zombies have taken the world!@C",255,0,0)
	end
end

addhook("reload","ZP.Reload")
function ZP.Reload(id,mode)
	if player(id,"team") == 2 and mode == 2 then
		if PLAYER[id].Survivor then
			if ZP_SURVIVOR_AMMO == 1 then
				parse("equip "..id.." "..player(id,"weapontype"))
			end
		else
			if ZP_HUMAN_AMMO == 1 then
				parse("equip "..id.." "..player(id,"weapontype"))
			end
		end
	end
end

addhook("attack","ZP.Attack")
function ZP.Attack(id)
	if player(id,"weapontype") > 0 and player(id,"team") == 2 then
		if PLAYER[id].Survivor then
			if ZP_SURVIVOR_AMMO == 2 then
				parse("equip "..id.." "..player(id,"weapontype"))
			end
		else
			if ZP_HUMAN_AMMO == 2 or PLAYER[id].InfClip then
				parse("equip "..id.." "..player(id,"weapontype"))
			end
		end
	elseif player(id,"team") == 1 then
		Sound3("starkkz/zombie/mz_knifeslash"..math.random(1,2)..".wav",player(id,"x"),player(id,"y"),280)
		if not PLAYER[id].Nemesis then
			if ZP.Class[PLAYER[id].Class].Attack then
				ZP.Class[PLAYER[id].Class].Attack(id)
			end
		end
	end
end

addhook("serveraction","ZP.Act")
function ZP.Act(id,act)
	if act == 1 then
		mainMenu.openTo(id,1)
	end
end

addhook("say","ZP.Say")
function ZP.Say(id,txt)
	if string.sub(txt,1,1) == "!" then
		local s = txt:split()
		if PLAYER[id].Admin() then
			if s[1] == "!setap" then
				local p = tonumber(s[2])
				local amount = tonumber(s[3])

				if p and amount and player(p,"exists") then
					PLAYER[p].set("AmmoPacks", amount)
					ZP.Msg2(id,"You set "..player(p,"name").."'s Ammo Packs to "..amount,0,255,0)
					ZP.Msg2(p,"An administrator set your Ammo Packs to "..amount,0,255,0)
				end
				return 1
			elseif s[1] == "!ac" then
				for _, p in pairs(player(0,"table")) do
					if PLAYER[p].Admin() then
						msg2(p,Color(50,145,0)..player(id,"name").." [Admin Chat]: "..string.sub(txt,5))
					end
				end
				return 1
			end
		end

		if s[1] == "!giveap" then
			local p = tonumber(s[2])
			local amount = tonumber(s[3])

			if p and amount and player(p,"exists") then
				if amount < 0 then
					ZP.Msg2(id,"You can't rob Ammo Packs to other users",255,0,0)
					return 1
				end

				if PLAYER[id].get("AmmoPacks") >= amount then
					PLAYER[p].set("AmmoPacks", PLAYER[p].get("AmmoPacks") + amount)
					PLAYER[id].set("AmmoPacks", PLAYER[id].get("AmmoPacks") - amount)

					PLAYER[id].UpdateHuds()
					PLAYER[p].UpdateHuds()

					ZP.Msg2(id,"You gave "..amount.." Ammo Packs to "..player(p,"name"),0,255,0)
					ZP.Msg2(p,player(id,"name").." gave you "..amount.." Ammo Packs",0,255,0)
				else
					ZP.Msg2(id,"Not enough ammo packs",255,0,0)
				end
			end
		else
			ZP.Msg2(id,'Command "'..s[1]..'" is unknown!', 255,0,0)
		end
		return 1
	end
end

addhook("mapchange","ZP.NewMap")
function ZP.NewMap()
	for _, id in pairs(player(0,"table")) do
		PLAYER[id].Save()
		ZP.Msg2(id,"Auto saving data!",0,255,0)
	end
end

addhook("parse","ZP.Parse")
function ZP.Parse(txt)
	local s = txt:split()
	if s[1] == "zpx_give_ap" then
		local pl = tonumber(s[2])
		local amount = tonumber(s[3])
		if pl and amount and player(pl,"exists") then
			PLAYER[pl].set("AmmoPacks", PLAYER[pl].get("AmmoPacks") + amount)

			ZP.Msg2(pl,"An admin gave you "..amount.." Ammo Packs",0,255,0)
			ZP.Print(player(pl,"name").." Received "..amount.." Ammo Packs",0,255,0)
		end
		return 1
	elseif s[1] == "zpx_set_ap" then
		local pl = tonumber(s[2])
		local amount = tonumber(s[3])
		if pl and amount and player(pl,"exists") then
			PLAYER[pl].set("AmmoPacks", amount)

			ZP.Msg2(pl,"An admin set your Ammo Packs to "..amount,0,255,0)
			ZP.Print(player(pl,"name").." New Ammo Packs: "..amount,0,255,0)
		end
		return 1
	elseif s[1] == "zpx_reload" then
		parse("changemap "..map("name"))
		return 1
	end
end

addhook("hit","ZP.PlayerHit")
function ZP.PlayerHit(id,source,wpn,hpdmg,apdmg)
	local totaldmg = hpdmg + apdmg
	if itemtype(wpn,"dmg") then
		totaldmg = itemtype(wpn,"dmg")
	end

	if ZP.CFG.ITEM[wpn] then
		totaldg = ZP.CFG.ITEM[wpn].DMG
	end

	if player(source,"exists") then
		if player(id,"team") == player(source,"team") then
			totaldmg = 0
		end
	end
	return ZP.Hit(id,source,wpn,totaldmg)
end

function ZP.Hit(id,source,wpn,totaldmg)
	if player(source,"exists") then
		if player(source,"team") == 1 then
			if PLAYER[source].Nemesis then
				totaldmg = math.floor((totaldmg/100)* math.random(ZP_NEMESIS_DMG[1],ZP_NEMESIS_DMG[2]))
			else
				totaldmg = math.floor((totaldmg/100)* math.random(ZP.Class[PLAYER[id].Class].Dmg[1],ZP.Class[PLAYER[id].Class].Dmg[2]))
			end
		elseif player(source,"team") == 2 then
			if PLAYER[source].Survivor then
				totaldmg = math.floor((totaldmg/100)* math.random(ZP_SURVIVOR_DMG[1],ZP_SURVIVOR_DMG[2]))
			else
				totaldmg = math.floor((totaldmg/100)* math.random(ZP_HUMAN_DMG[1],ZP_HUMAN_DMG[2]))
			end
		end

		PLAYER[source].set("Damage", PLAYER[source].get("Damage")+totaldmg)

		if PLAYER[source].get("Damage") >= ZP_DAMAGE_PER_AP then
			PLAYER[source].set("AmmoPacks", PLAYER[source].get("AmmoPacks") + ZP_AP_PER_DAMAGE)
			PLAYER[source].set("Damage", 0)
		end

		PLAYER[source].DamageMessage = Millisecs()
		if totaldmg > 0 then
			PLAYER[source].Hudtxt(2,totaldmg,310,200,70,70,255)
		end
		PLAYER[source].UpdateHuds()
	end

	local newArmor = PLAYER[id].ArmorProtection - totaldmg
	local newHealth = PLAYER[id].HealthProtection
	if newArmor <= 0 then
		newHealth = newHealth + newArmor
		newArmor = 0
	end
	hpdmg = PLAYER[id].HealthProtection - newHealth
	apdmg = PLAYER[id].ArmorProtection - newArmor

	PLAYER[id].DamageMessage = Millisecs()
	if totaldmg > 0 then
		PLAYER[id].Hudtxt(2,totaldmg,310,200,255,0,0)
	end

	if PLAYER[id].HealthProtection - hpdmg > 0 then
		PLAYER[id].HealthProtection = PLAYER[id].HealthProtection - hpdmg
		PLAYER[id].ArmorProtection = PLAYER[id].ArmorProtection - apdmg

		if player(source,"exists") then
			if player(id,"team") == 1 then
				PLAYER[id].Knockback(player(source,"x"),player(source,"y"),math.floor(totaldmg/4))
				if PLAYER[id].Nemesis then
					PLAYER[id].KnockSlow = math.floor(totaldmg/2)
				else
					PLAYER[id].KnockSlow = math.floor(totaldmg/3.5)
				end

				if wpn == 51 then
					PLAYER[id].BurnTime = Millisecs() + ZP_BURN_TIME*1000
				elseif wpn == 46 then
					PLAYER[id].BurnTime = Millisecs() + 2000
				end
			else
				PLAYER[id].KnockSlow = math.floor((totaldmg/3)*0.7)
				if wpn == 78 and totaldmg > 0 then
					Sound3("starkkz/zombie/mz_zattack"..math.random(1,3)..".wav",player(id,"x"),player(id,"y"),380)
				end
			end
		end

		if player(id,"team") == 1 then
			if PLAYER[id].Nemesis then
				if Millisecs() - PLAYER[id].lastPainSound >= 0 then
					local soundLength = {1290,1209,1246}
					local painSound = math.random(1,3)

					PLAYER[id].lastPainSound = Millisecs() + soundLength[painSound]
					Sound3("starkkz/zombie/nemesis_pain"..painSound..".wav",player(id,"x"),player(id,"y"),380)
				end
			else
				if Millisecs() - PLAYER[id].lastPainSound >= 0 then
					local soundLength = {683,536,940,608,475}

					local playSoundAuth = 1
					if ZP.Class[PLAYER[id].Class].Hit then
						playSoundAuth = ZP.Class[PLAYER[id].Class].Hit(id,source,wpn,hpdmg,apdmg) or 1
					end
					if playSoundAuth == 1 then
						local painSound = math.random(1,5)

						PLAYER[id].lastPainSound = Millisecs() + soundLength[painSound]
						Sound3("starkkz/zombie/zombie_pain"..painSound..".wav",player(id,"x"),player(id,"y"),380)
					end
				end
			end
		end

		PLAYER[id].UpdateSpeed()
	else
		if player(source,"exists") and player(source,"team") == 1 and player(id,"team") == 2 then
			PLAYER[id].Survivor = false
			PLAYER[id].UpdateGlow()
			if not PLAYER[source].Nemesis then
				PLAYER[id].enableSwitchTeam()
				Sound3("starkkz/zombie/infect_"..math.random(1,4)..".ogg",player(id,"x"),player(id,"y"),380)
			end

			local x,y = player(id,"x"), player(id,"y")
			if wpn == 78 then
				if PLAYER[source].Nemesis then
					parse('customkill '..source..' "Nemesis Claw" '..id)
				else
					parse('customkill '..source..' "Infected" '..id)
				end
			else
				parse('customkill '..source..' "'..ItemName(wpn)..'" '..id)
			end

			if not PLAYER[source].Nemesis then
				parse("spawnplayer "..id.." "..x.." "..y)

				if ZP.Class[PLAYER[id].Class].Kill then
					ZP.Class[PLAYER[id].Class].Kill(id,source)
				end
			end
		else
			parse('customkill '..source..' "'..ItemName(wpn)..'" '..id)
		end
	end

	if PLAYER[id].ArmorProtection < 0 then PLAYER[id].ArmorProtection = 0 end
	if PLAYER[id].HealthProtection < 0 then PLAYER[id].HealthProtection = 0 end
	PLAYER[id].UpdateProtection()
	PLAYER[id].UpdateHuds()
	return 1
end

ZP.LoadCFG()
ZP.LoadMenus()
